package cn.xk.ymcc.service.impl;

import cn.xk.ymcc.domain.Blacklist;
import cn.xk.ymcc.domain.MessageSms;
import cn.xk.ymcc.domain.User;
import cn.xk.ymcc.domain.dto.SendSmsDto;
import cn.xk.ymcc.exception.BusinessException;
import cn.xk.ymcc.mapper.BlacklistMapper;
import cn.xk.ymcc.mapper.MessageSmsMapper;
import cn.xk.ymcc.service.IVerifyCodeService;
import cn.xk.ymcc.util.StrUtils;
import cn.xk.ymcc.util.VerifyCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private MessageSmsMapper messageSmsMapper;

    @Override
    public void sendCode(SendSmsDto dto) {
        //2.根据当前的手机号以及作用 尝试去redis获取验证码
        Object phoneCodeObj = redisTemplate.opsForValue().get("register:" + dto.getMobile());//获取key
        //3.如果有 两次请求的时间间隔是否大于60秒
        //3.1 小于60秒 抛出异常--不合法的请求
        //3.2 大于60秒 获取上一次发送的验证码
        String phoneCode = null;//置空
        if (phoneCodeObj == null) {
            //2.1.为空 = 第一次发送或手机验证码过期了 => 重新生成一个
            phoneCode = StrUtils.getRandomString(4);
        } else {
            //2.2.不为空 = 手机验证码没有过期。判断是否过了重发时间
            long now = System.currentTimeMillis();//当前的时间-新时间
            long old = Long.parseLong(phoneCodeObj.toString().split(":")[1]);//发送验证码的时间
            if ((now - old) < 1 * 60 * 1000) {//60000ms是一分钟
                //2.2.1.没有过重发时间 = 违规操作【抛业务异常】
                throw new BusinessException("请勿重复发送验证码!!!");
            } else {
                //2.2.2.过了重发时间 = 可以重新发送【用没有过期的那个验证码】
                phoneCode = phoneCodeObj.toString().split(":")[0];
            }
        }
        //4.发送验证码
        //3.刷新过期时间 = 重新添加一次数据到redis
        redisTemplate.opsForValue().set("register:" + dto.getMobile()
                , phoneCode + ":" + System.currentTimeMillis(), 5, TimeUnit.MINUTES);//设置当前
        //三：调用第三方接口发送短信验证码：调用工具类
        //SmsUtils.sendSms(dto.getPhone(),"你的手机验证码是：" + phoneCode+",请在3分钟内使用!!!");
        log.info("你的手机验证码是：" + phoneCode + ",请在3分钟内使用!!!");

        //5.把验证码发送 记录到数据库
        MessageSms sms = new MessageSms();
        sms.setTitle("注册验证码");
        sms.setContent("你的手机验证码是：" + phoneCode + ",请在3分钟内使用!!!");
        sms.setSendTime(new Date());
        sms.setPhone(dto.getMobile());
        //获取当前的请求
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取ip地址
        String ip = requestAttributes.getRequest().getRemoteAddr();
        sms.setIp(ip);
        //把验证码发送记录 报错到数据库
        messageSmsMapper.insert(sms);
        
    }


    @Override
    public String getImageCode(String key) {
        //1、获取图形验证码
        String imageCode = StrUtils.getComplexRandomString(4);
        //2、保存到redis
        redisTemplate.opsForValue().set(key, imageCode, 3, TimeUnit.MINUTES);
        //3、返回基于base64编码的图形字符串
        return VerifyCodeUtils.verifyCode(115, 40, imageCode);
    }

}
